<h2>Physics Tutorial 1: Colliding Rectangles</h2>
<p>
	In this tutorial, we set up a simulation in which rectangles
	collide with each other and the walls, bouncing in physically realistic ways.
</p>

<p>
	<b>Note:</b> The physics tutorials assume you are comfortable with using the basics of the MASON
	simulator. 
</p>

<p>
	This tutorial teaches:
	<ul>
		<li>How to build a basic physics simulation</li>
		<li>How to create and configure mobile objects</li>
		<li>How to create and configure stationary objects</li>
		<li>How to register physical objects with the physics engine</li>
	</ul>
</p>

<h2>Create a MobilePoly</h2>
<p>
	In the <b>sim/app/physicsTutorial1</b> directory, create a file called <b>MobilePoly.java</b>.
	In this file add:
</p>
<pre>
package sim.app.physicsTutorial1;

import java.awt.*;
import sim.engine.*;
import sim.physics2D.physicalObject.*;
import sim.physics2D.util.*;

public class MobilePoly extends MobileObject2D implements Steppable
{	
	public MobilePoly(Double2D pos, Double2D vel, double width, double height, Paint paint)
	{
		// initial position and velocity
		this.setVelocity(vel);
		this.setPose(pos, new Angle(0));
		
		// shape - determines how the object will look and how collision detection is done
		this.setShape(new sim.physics2D.shape.Rectangle(width, height, paint), width * height);

		// physical properties
		this.setCoefficientOfFriction(0);
		this.setCoefficientOfRestitution(1);
	}
}
</pre>
<p>
	The rectangles in this simulation are "mobile objects" (as opposed to "stationary objects," 
	like walls). The physics simulator implements much of the logic needed to simulate mobile
	objects in the class sim.physics2D.physicalObject.<b>MobileObject2D</b>. Create a mobile
	object by inheriting from this class and then defining its specific attributes and behavior.	
</p>
<p>
	The first thing that gets set up in <b>MobilePoly</b> is its initial position and velocity
	by calling the <b>setVelocity</b> and <b>setPose</b> methods provided by <b>MobileObject2D</b>.
	This tells the physics engine where the objects are and how fast they are going when the simulation
	starts.
</p>
<p>
	A <b>MobileObject2D</b> has no associated shape until one is provided. In this case, we use
	<b>sim.physics2D.shape.Rectangle</b> for the shape. The second parameter passed to <b>setShape</b>
	is the object's mass. To make larger rectangles act heavier, I assumed that the rectangles mass is 
	given by its area (width * height).
</p>
<p>
	The last two method calls set some physical parameters for the object. 
	The "Coefficient of Friction" tells the simulator
	how easily the objects slides over the background. A value of "0" means that the object is 
	perfectly slippery - kind of like a puck on ice. As the value for the friction coefficient increases
	the object gets less slippery. The "Coefficient of Restitution" determines
	how elastic the object is - how hard it rebounds from collisions. A value of 1 indicates 
	perfect elasticity (like a super ball), while a value of 0 means the object is totally 
	inelastic (like a flat basketball). After getting the simulation working, try playing around
	with different values for these two coefficients.
</p>
<p>
	After setting up the constructor, finish the mobile poly by adding the code for the <b>step</b>
	method:
</p>
<pre>
	public void step(SimState state)
	{
		Double2D position = this.getPosition();
		PhysicsTutorial1 simPhysicsTutorial1 = (PhysicsTutorial1)state;
		simPhysicsTutorial1.fieldEnvironment.setObjectLocation(this, new sim.util.Double2D(position.x, position.y));
	}
</pre>
<p>
	As the simulation proceeds, the physics engine updates objects' positions based on their
	velocities, the forces and torques applied to them, and any collisions involving them. A mobile
	object can determine where it is at the current timestep with a call to <b>MobileObject2D</b>'s
	<b>getPosition</b> method. One thing to note here is that the physics engine provides its own
	<b>Double2D</b> class (sim.app.physics2D.util.<b>Double2D</b>) that is separate from MASON's
	<b>sim.util.Double2D</b> class.
</p>
<h2>Create a Wall</h2>
<p>
	In the <b>sim/app/physicsTutorial1</b> directory, create a file called <b>Wall.java</b>.
	In this file add:
</p>
<pre>
package sim.app.physicsTutorial1;

import java.awt.*;
import sim.physics2D.physicalObject.*;
import sim.physics2D.util.*;

public class Wall extends StationaryObject2D
{
	public double radius;
	public Wall(Double2D pos, int width, int height)
	{
		this.setCoefficientOfRestitution(1);
		this.setPose(pos, new Angle(0));
		this.setShape(new sim.physics2D.shape.Rectangle(width, height, Color.white, true));
	}
}
</pre>
<p>
	A <b>Wall</b>, unlike a <b>MobilePoly</b>, is a "stationary object" - it has an infinite mass 
	so it does not move at all as a result of collisions or forces. In this physics engine, this 
	is represented by <b>StationaryObject2D</b>.
</p>
<p>
	The rest of the code for the wall is similar to that of <b>MobilePoly</b> except for the final
	parameter passed to the <b>Rectangle</b> constructor. The value of true for this parameter
	tells the <b>Rectangle</b> that it is a stationary object. It is not necessary to provide 
	the <b>Rectangle</b> with this information, but doing so increases efficiency by allowing the 
	<b>Rectangle</b> to cache data about it's vertices' positions and to provide more accurate
	information about its endpoints to be used for collision detection.
</p>
<h2>Set up the physics simulation in the MASON <b>SimState</b>'s start method</h2>
<p>
	The file <b>sim/app/physicsTutorial1/PhysicsTutorial1.java</b> already has much of 
	the non-physics related MASON code needed to set up the simulation. The only code
	to add is in the <b>start</b> method.
	The following code blocks get added sequentially starting at the 
	"Add physics specific code here" line.
</p>
<h3>
	Create and schedule the physics engine
</h3>
<pre>
	// Create and schedule the physics engine
	PhysicsEngine2D objPE = new PhysicsEngine2D();
	schedule.scheduleRepeating(objPE);
</pre>
<p>
	<b>PhysicsEngine</b> coordinates all the activities performed by the physics
	simulator. It needs to run at every times step, so it needs to be scheduled
	with the MASON scheduler.
</p>
<h3>Set up the walls</h3>
<pre>
		Double2D pos;
		
		// WALLS
		// HORIZ
		Wall wall;
		pos = new Double2D(100, 0);
		wall = new Wall(pos, 200, 6);
		fieldEnvironment.setObjectLocation(wall, new sim.util.Double2D(pos.x, pos.y));
		objPE.register(wall);
 
		pos = new Double2D(100,200);
		wall = new Wall(pos, 200, 6);
		fieldEnvironment.setObjectLocation(wall, new sim.util.Double2D(pos.x, pos.y));
		objPE.register(wall);
		
		// VERT
		pos = new Double2D(0, 100);
		wall = new Wall(pos, 6, 200);
		fieldEnvironment.setObjectLocation(wall, new sim.util.Double2D(pos.x, pos.y));
		objPE.register(wall);
	
		pos = new Double2D(200, 100);
		wall = new Wall(pos, 6, 200);
		fieldEnvironment.setObjectLocation(wall, new sim.util.Double2D(pos.x, pos.y));
		objPE.register(wall);
</pre>
<p>
	This code creates four rectangles and places them around the simulation "floor." 
	The horizontal walls are 200 units wide and 6 units tall. The position given for 
	each wall specifies where its center should go.
	
	The walls are not scheduled with the MASON scheduler because they don't do anything
	except sit there. They do, however, need to be registered with the physics engine
	so it will know if other objects collide with them. In general, any object that
	needs to be considered by the physics engine needs to be registered at the beginning
	of the simulation.
</p>	
<h3>Set up the mobile polys</h3>
<pre>
		Double2D vel;

		MobilePoly rec;
		for (int i = 0; i < 4; i++)
		{
			pos = new Double2D(Math.max(Math.min(random.nextDouble() * 200, 190), 10), Math.max(Math.min(random.nextDouble() * 200, 190), 10));
			vel = new Double2D(random.nextDouble() * 1.5, random.nextDouble() * 1.5);
			rec = new MobilePoly(pos, vel, 15, 30, Color.red);
			fieldEnvironment.setObjectLocation(rec, new sim.util.Double2D(pos.x, pos.y));
			objPE.register(rec);
			schedule.scheduleRepeating(rec);
		}
</pre>
<p>
	This creates four mobile polys in random locations and random velocities. The mobile
	polys need to be scheduled with the MASON scheduler and registered with the physics engine.
</p>
<h2>Run the simulation</h2>
<p>
	Compile MobilePoly.java, Wall.java, PhysicsTutorial1.java, and PhysicsTutorial1WithUI.java. Then run the program 
	as <b>java sim.app.physicsTutorial1.PhysicsTutorial1WithUI</b>
</p>
<p>
	After pressing play, you should see four red rectangles moving around and 
	colliding with each other and the walls.
</p>

